"""
统一的依赖注入管理
提供通用的认证、权限、分页等依赖
"""

from typing import Optional, Annotated
from fastapi import Depends, Query, Request
from app.core.auth import get_current_user_required, get_current_user_optional, get_current_superuser
from app.schemas.base.login import JWTPayload
from app.utils.app_log import logger

from typing import Optional
import jwt
from fastapi import Depends, Header,  Request
from app.utils.request import RequestHandler

from app.core.user import CTX_USER_ID
from app.models import Role, User
from app.core.config import settings


class AuthControl:
    @classmethod
    async def is_authed(cls, token: str = Header(..., description="token验证")) -> Optional["User"]:
        try:
            if token == "dev":
                user = await User.filter().first()
                user_id = user.id
            else:
                decode_data = jwt.decode(token, settings.SECRET_KEY, algorithms=settings.JWT_ALGORITHM)
                user_id = decode_data.get("user_id")
            user = await User.filter(id=user_id).first()
            if not user:
                raise RequestHandler.error(code=401, remarks="Authentication failed")
            CTX_USER_ID.set(int(user_id))
            return user
        except jwt.DecodeError:
            raise RequestHandler.error(code=401, remarks="无效的Token")
        except jwt.ExpiredSignatureError:
            raise RequestHandler.error(code=401, remarks="登录已过期")
        except Exception as e:
            raise RequestHandler.error(code=500, remarks=f"{repr(e)}")


class PermissionControl:
    @classmethod
    async def has_permission(cls, request: Request, current_user: JWTPayload = Depends(get_current_user_required)) -> None:
        if current_user.is_superuser:
            return
        method = request.method
        path = request.url.path
        # TODO: 实现权限检查逻辑
        # 这里需要根据用户角色检查API权限
        logger.info(f"检查用户 {current_user.user_id} 对 {method} {path} 的权限")


DependAuth = Depends(get_current_user_required)
DependPermission = Depends(PermissionControl.has_permission)



# 认证相关依赖
CurrentUser = Annotated[JWTPayload, Depends(get_current_user_required)]
CurrentUserOptional = Annotated[Optional[JWTPayload], Depends(get_current_user_optional)]  
SuperUser = Annotated[JWTPayload, Depends(get_current_superuser)]


class PaginationParams:
    """分页参数"""
    def __init__(
        self,
        page: int = Query(1, ge=1, description="页码"),
        page_size: int = Query(10, ge=1, le=100, description="每页数量")
    ):
        self.page = page
        self.page_size = page_size
        self.offset = (page - 1) * page_size


class SortParams:
    """排序参数"""
    def __init__(
        self,
        order_by: str = Query("-created_at", description="排序字段，支持负号表示降序"),
        order_type: str = Query("desc", regex="^(asc|desc)$", description="排序方式")
    ):
        self.order_by = order_by
        self.order_type = order_type
        
        # 处理排序字段
        if order_by.startswith("-"):
            self.field = order_by[1:]
            self.direction = "desc"
        elif order_by.startswith("+"):
            self.field = order_by[1:]
            self.direction = "asc"
        else:
            self.field = order_by
            self.direction = order_type
    
    def get_order_string(self) -> str:
        """获取Tortoise ORM排序字符串"""
        return f"-{self.field}" if self.direction == "desc" else self.field


class SearchParams:
    """搜索参数"""
    def __init__(
        self,
        search: Optional[str] = Query(None, max_length=100, description="搜索关键词"),
        search_fields: Optional[str] = Query(None, description="搜索字段，逗号分隔")
    ):
        self.search = search
        self.search_fields = search_fields.split(",") if search_fields else []


# 创建依赖注入的别名
Pagination = Annotated[PaginationParams, Depends(PaginationParams)]
Sort = Annotated[SortParams, Depends(SortParams)]
Search = Annotated[SearchParams, Depends(SearchParams)]


def get_family_id(
    family_id: int = Query(..., description="家庭ID")
) -> int:
    """获取家庭ID依赖"""
    return family_id


def get_optional_family_id(
    family_id: Optional[int] = Query(None, description="家庭ID（可选）")
) -> Optional[int]:
    """获取可选家庭ID依赖"""
    return family_id


# 家庭相关依赖
FamilyId = Annotated[int, Depends(get_family_id)]
OptionalFamilyId = Annotated[Optional[int], Depends(get_optional_family_id)]


class PermissionChecker:
    """权限检查器"""
    
    @staticmethod
    def check_family_access(user: JWTPayload, family_id: int):
        """
        检查用户是否有家庭访问权限
        
        Args:
            user: 当前用户
            family_id: 家庭ID
            
        Raises:
            HTTPException: 权限不足时抛出403异常
        """
        # 超级用户拥有所有权限
        if user.is_superuser:
            return
        
        # TODO: 实现具体的家庭权限检查逻辑
        # 这里需要查询用户是否是该家庭的成员
        logger.info(f"检查用户 {user.user_id} 对家庭 {family_id} 的访问权限")
    
    @staticmethod
    def check_resource_owner(user: JWTPayload, resource_user_id: int):
        """
        检查用户是否是资源所有者
        Args:
            user: 当前用户
            resource_user_id: 资源所有者ID
        """
        if user.is_superuser:
            return
        
        if user.user_id != resource_user_id:
            raise RequestHandler.forbidden(
                message ="权限不足，只能访问自己的资源"
            )


def check_family_permission(
    current_user: CurrentUser,
    family_id: FamilyId
):
    """家庭权限检查依赖"""
    PermissionChecker.check_family_access(current_user, family_id)
    return current_user


def check_owner_permission(
    current_user: CurrentUser,
    resource_user_id: int = Query(..., description="资源所有者ID")
):
    """资源所有者权限检查依赖"""
    PermissionChecker.check_resource_owner(current_user, resource_user_id)
    return current_user


# 权限相关依赖
FamilyUser = Annotated[JWTPayload, Depends(check_family_permission)]
OwnerUser = Annotated[JWTPayload, Depends(check_owner_permission)]


class CommonQueryParams:
    """通用查询参数组合"""
    def __init__(
        self,
        pagination: Pagination,
        sort: Sort,
        search: Search
    ):
        self.pagination = pagination
        self.sort = sort
        self.search = search


# 通用查询参数组合
CommonQuery = Annotated[CommonQueryParams, Depends(CommonQueryParams)]


def get_request_info(request: Request) -> dict:
    """获取请求信息依赖"""
    return {
        "method": request.method,
        "url": str(request.url),
        "headers": dict(request.headers),
        "client": request.client.host if request.client else None
    }


# 请求信息依赖
RequestInfo = Annotated[dict, Depends(get_request_info)]




